import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.JComboBox;
import javax.swing.JTextField;

import jpcap.packet.Packet;


public class User_Connections{
	private HashMap<String,byte[]> userdata = new HashMap();
	private HashMap<String,HashMap<String,byte[]>> userdata_ip = new HashMap();
	private HashMap<String,Packet> next_packet = new HashMap();			//For holding the next TCP Packet
	private utils util = new utils();
	public int number_of_connections = 0;
	/**
	* checks if the key already exists; key defined by source IP:Dest IP
	* and checks bothways if it does not exist create new entry..
	* Entry is converted to byte[].
	* @param pb
	*/
	public void save_to_hashmap(Packet_Builder pb,ArrayList<String> al,
			HashMap<String, ArrayList<String>> connection_users_ip,JComboBox update,JComboBox update_ip)
	{		
		String key_mac = null;
		String key_ip = null;		
			if((key_mac=check_Contains_Key(pb,true,key_mac)).compareTo(" ")!=0)
			{							
				if((key_ip=check_Contains_Key(pb,false,key_mac)).compareTo(" ")!=0)
				{
					String c = new String(userdata_ip.get(key_mac).get(key_ip));
					c = c.concat(store_connection_data(pb));
					userdata.putAll(userdata_ip.get(key_mac));
					userdata.put(key_ip, c.getBytes());
					userdata_ip.put(key_mac,userdata);	
				}else
				{
					ArrayList<String> temp = new ArrayList<String>();
					String s = (String)update.getSelectedItem();			
					key_ip = pb.src_ip.getHostAddress() + ":" + pb.dst_ip.getHostAddress();		
					userdata.putAll(userdata_ip.get(key_mac));
					userdata.put(key_ip,store_connection_data(pb).getBytes());				
					userdata_ip.put(key_mac,userdata);			
					temp = (ArrayList<String>) connection_users_ip.get(key_mac);
					temp.add(key_ip);
					connection_users_ip.put(key_mac, temp);					
					if(s.compareTo(key_mac)==0)
						update_ip.addItem((String)connection_users_ip.get(key_mac).get(connection_users_ip.get(key_mac).size()-1));					
				}
			}else
			{
				ArrayList<String> temp = new ArrayList<String>();				
				key_mac = pb.ep.getSourceAddress() + ":" + pb.ep.getDestinationAddress();
				key_ip = pb.src_ip.getHostAddress() + ":" + pb.dst_ip.getHostAddress();
				userdata = new HashMap();				
				userdata.put(key_ip,store_connection_data(pb).getBytes());				
				userdata_ip.put(key_mac,userdata);		
				temp.add(key_ip);
				al.add(key_mac);				
				connection_users_ip.put(key_mac, temp);
				update.addItem(al.get(number_of_connections));
				String s = (String)update.getSelectedItem();				
				number_of_connections++;				
			}			
			if(pb.protocol==6)	
			{		
				next_packet.put(key_ip,pb.pkt);		
			}			
	}
	/**
	 * Check MAC Address or IP to insert into hash 
	 * @param pb
	 * @return
	 */
	String check_Contains_Key(Packet_Builder pb,boolean MAC,String key)
	{
		if(MAC)
		{
			String key_mac = pb.ep.getSourceAddress() + ":" + pb.ep.getDestinationAddress();
			if(userdata_ip.containsKey(key_mac)) return key_mac;
			
			String key_mac2 = pb.ep.getDestinationAddress() + ":" + pb.ep.getSourceAddress();	
			if(userdata_ip.containsKey(key_mac2)) return key_mac2;	
							
		}else
		{
			String conversation_ip = pb.src_ip.getHostAddress() + ":" + pb.dst_ip.getHostAddress();
			if(userdata_ip.get(key).containsKey(conversation_ip)) return conversation_ip;
			
			String conversation_ip2 = pb.dst_ip.getHostAddress() + ":" + pb.src_ip.getHostAddress();
			if(userdata_ip.get(key).containsKey(conversation_ip2)) return conversation_ip2;					
		}
		
		return " ";
		
	}
	
	/**
	 * Save the text in a string..
	 * @param pb
	 * @return
	 */
	String store_connection_data(Packet_Builder pb)
	{
		String frame="", ethernet = "", ipv4 = "", tcporudp= "", data="";
			
			ethernet = ethernet.concat("*******************************************START PACKET*******************************************\n")
			.concat("*******************************************ETHERNET*************************************************\n")
			.concat("Source MAC: " + pb.ep.getSourceAddress() + "\n")
			.concat("Destination MAC: " + pb.ep.getDestinationAddress() + "\n")
			.concat("Frame Type: " + "0x" + Integer.toHexString(pb.ep.frametype) + "\n");
		if(Integer.toHexString(pb.frametype).compareTo("800")==0) //Frame 0x800 = TCP/IP : UDP Type
		{
			ipv4 = ipv4.concat("***********************************INTERNET PROTOCOL VERSION 4 HEADER**********************************\n")
			.concat("Source IP: " + pb.src_ip.getHostAddress() + "\n")
			.concat("Source Port: " + pb.src_port + "\n")
			.concat("Destination IP: " + pb.dst_ip.getHostAddress() + "\n")
			.concat("Destination Port: " + pb.dst_port + "\n")
			.concat("Version: " + pb.version + "\n")
			.concat("TOS: " + pb.rsv_tos + "\n")
			.concat("Total Length: " + pb.length + "\n")
			.concat("Identification: " + pb.ident + "\n")
			.concat("Dont Frag: " + pb.dont_frag +"   " + "More Frag: " + pb.more_frag +"\n")
			.concat("Frag Offset: " + pb.offset + "\n")
			.concat("TTL: " + pb.hop_limit + "\n")
			.concat("Protocol: " + pb.protocol + "\n")
			.concat("IPV4 Checksum: " + pb.checksum_ipv4 + "\n");
			if(pb.protocol==6)
			{
				tcporudp = tcporudp.concat("*******************************************TCP/IP HEADER*******************************************\n")
				.concat("Seq Num: " + pb.sequence + "\n")
				.concat("Ack Num: " + pb.ack_num + "\n")
				.concat("Flags [URG: " + pb.urg +" ACK:"+pb.ack+" PSH:"+pb.psh+ " RST:"+pb.psh+" SYN:" +pb.syn + " FIN:" +pb.fin+"]\n")
				.concat("Window Size: " + pb.window + "\n")
				.concat("TCP/IP Checksum: " + pb.checksum_tcp + "\n");
			}else
			{
				tcporudp = tcporudp.concat("*******************************************UDP HEADER*******************************************\n")
				.concat("UDP Length: " + pb.udp_Length + "\n")
				.concat("UDP Checksum: " + pb.checksum_udp + "\n");
			}
			data = data.concat("Header Hexadec : " + util.toReadbleHex(pb.pkt.header) + "\n")
			.concat("Header size : " + pb.pkt.header.length + "\n")
			.concat("Data Hexadec : " + util.toReadbleHex(pb.pkt.data) + "\n")			
			.concat("Data size : " + pb.pkt.data.length + "\n")	
			.concat("*******************************************End of Packet*******************************************\n\n");			
		}
		frame = frame.concat(ethernet).concat(ipv4).concat(tcporudp).concat(data);
		return frame;
	}
	
	public ArrayList<String> getAllusers()
	{
		ArrayList<String> allusers = new ArrayList<String>();
		Iterator iter = userdata.keySet().iterator();
		for(int a =0;iter.hasNext();a++)
		{
			allusers.add((String) iter.next());
		}
		return allusers;
	}
	
	public String getUser(String usr, String mac)
	{
		return new String(userdata_ip.get(mac).get(usr));
	}
	
	public Packet_Builder getHash_packet_builder(String ip) throws UnknownHostException
	{
		
		Packet pb = null;		
			pb = next_packet.get(ip);
			if(pb!=null)
				return new Packet_Builder(pb);	
			else
				return null;				
	}
	
}
